package org.example.pingpong.service.Impl;

import org.example.pingpong.service.RedisService;
import org.example.pingpong.utils.JwtUtil;
import org.example.pingpong.utils.ThreadLocalUtil;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;

@Service
public class RedisServiceImpl implements RedisService {
    @Resource
    RedisTemplate<String, String> redisTemplate;

    /**
     * 设置缓存中的值，未指定过期时间。
     *
     * @param key   缓存的键
     * @param value 缓存的值
     */
    private void set(String key, String value) {
        redisTemplate.opsForValue().set(key, value);
    }

    /**
     * 设置缓存中的值，并指定过期时间。
     *
     * @param key            缓存的键
     * @param value          缓存的值
     * @param expirationTime 缓存的过期时间（单位：秒）
     */
    private void set(String key, String value, long expirationTime) {
        redisTemplate.opsForValue().set(key, value, expirationTime, TimeUnit.SECONDS);
    }

    /**
     * 获取缓存中的值。
     *
     * @param key 缓存的键
     * @return 缓存中的值，如果未找到则返回 null
     */
    private String get(String key) {
        return redisTemplate.opsForValue().get(key);
    }

    /**
     * 删除缓存中的值。
     *
     * @param key 缓存的键
     */
    private void del(String key) {
        redisTemplate.delete(key);
    }

    /**
     * 设置验证码缓存，默认过期时间为5分钟。
     *
     * @param recipient      收件人邮箱地址
     * @param mailCode       需要缓存的验证码
     * @param expirationTime 验证码的过期时间，单位：秒（默认为300秒，5分钟）
     */
    @Override
    public void setMailCode(String recipient, String mailCode, long expirationTime) {
        // 如果未指定过期时间，使用默认值（5分钟）
        if (expirationTime <= 0) {
            expirationTime = 300; // 默认过期时间：5分钟
        }
        set(recipient, mailCode, expirationTime); // 设置验证码缓存并指定过期时间
    }

    /**
     * 获取验证码缓存。
     *
     * @param recipient 用于获取验证码的唯一标识符（如邮箱地址）
     * @return 缓存中的验证码，若未找到则返回 null
     */
    @Override
    public String getMailCode(String recipient) {
        return get(recipient); // 获取指定收件人的验证码
    }

    /**
     * 删除验证码缓存。
     *
     * @param recipient 需要删除验证码缓存的收件人邮箱地址
     */
    @Override
    public void delMailCode(String recipient) {
        String code = getMailCode(recipient); // 获取验证码
        if (code != null && !code.isEmpty()) {
            del(recipient); // 删除验证码缓存
        }
    }

    /**
     * 设置JWT令牌缓存，并指定过期时间。
     *
     * @param jwtToken      需要缓存的JWT令牌
     * @param expirationTime 令牌的过期时间（单位：秒）
     */
    @Override
    public void setJwtToken(String jwtToken, long expirationTime) {
        redisTemplate.opsForValue().set(jwtToken, jwtToken, expirationTime, TimeUnit.SECONDS);
    }

    /**
     * 删除JWT令牌缓存。
     *
     * @param jwtToken 需要删除的JWT令牌
     */
    @Override
    public void delJwtToken(String jwtToken) {
        del(jwtToken); // 删除指定的JWT令牌缓存
    }

    /**
     * 生成新的JWT令牌，并将其缓存。
     *
     * @return 新生成的JWT令牌
     */
    @Override
    public String newJwtToken() {
        // 删除当前线程的旧JWT令牌缓存
        del(ThreadLocalUtil.getJWT());
        // 使用ThreadLocal中的用户信息生成新的JWT令牌
        String token = JwtUtil.genToken(ThreadLocalUtil.get());
        // 将新生成的令牌缓存，过期时间为3天
        setJwtToken(token, 3 * 24 * 60 * 60);
        return token;
    }
}
